home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Languguage OS 2
/
Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO
/
gnu
/
superopt.lha
/
superopt-2.2
/
superopt.h
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-15
|
22KB
|
749 lines
/* Superoptimizer definitions.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !(defined(SPARC) || defined(RS6000) || defined(M88000) \
|| defined(AM29K) || defined(MC68000) || defined(MC68020) \
|| defined(I386) || defined(PYR) || defined(ALPHA))
/* If no target instruction set is defined, use host instruction set. */
#define SPARC (defined(sparc) || defined(__sparc__))
#define RS6000 (defined(rs6000) || defined(_IBMR2))
#define M88000 (defined(m88000) || defined(__m88000__))
#define AM29K (defined(_AM29K) || defined(_AM29000))
#define MC68020 (defined(m68020) || defined(mc68020))
#define MC68000 (defined(m68000) || defined(mc68000))
#define I386 (defined(i386) || defined(i80386))
#define PYR (defined(pyr) || defined(__pyr__))
#define ALPHA defined(__alpha)
#endif
#define M68000 (MC68000 || MC68020)
#if !(SPARC || RS6000 || M88000 || AM29K || M68000 || I386 || PYR || ALPHA)
You have to choose target CPU type (e.g. -DSPARC).
#endif
#if MC68000
#define SHIFT_COST(CNT) ((8+2*(CNT)) / 5) /* internal cost */
#else
#define SHIFT_COST(CNT) 1
#endif
#ifndef USE_ASM
#define NO_ASM 1
#endif
#include "longlong.h"
#if ALPHA
#define BITS_PER_WORD 64
#else /* ! ALPHA */
#define BITS_PER_WORD 32
#endif
#if BITS_PER_WORD == 64
#ifdef __GNUC__
typedef unsigned long long int unsigned_word;
typedef signed long long int signed_word;
typedef unsigned_word word;
#elif __alpha /* Native compiler on alpha has 64 bit longs. */
typedef unsigned long int unsigned_word;
typedef signed long int signed_word;
typedef unsigned_word word;
#else /* Not on alpha, not GCC. Don't have 64 bit type. */
#error Do not know how to perform 64 bit arithmetic with this compiler.
#endif
#else
typedef unsigned int unsigned_word;
typedef signed int signed_word;
typedef unsigned_word word;
#endif
#define TRUNC_CNT(cnt) ((cnt) & (BITS_PER_WORD - 1))
#if defined(sparc) || defined(__GNUC__)
#define alloca __builtin_alloca
#endif
#if !defined(__GNUC__) || !defined(__OPTIMIZE__)
#define inline /* Empty */
#endif
/* The IMMEDIATE_* macros are for printing assembler. NOT for sequence
generating or analyze. */
#define IMMEDIATE_P(op) (op >= 0x20 - 3)
static const word __immediate_val[] =
{
(word) 1 << (BITS_PER_WORD - 1),
((word) 1 << (BITS_PER_WORD - 1)) - 1,
};
#define IMMEDIATE_VAL(op) \
((op) >= 0x20 - 1 ? op - 0x20 : __immediate_val[0x20 - 2 - (op)])
/* Handle immediates by putting all handled values in the VALUE array at
appropriate indices, and then insert these indices in the code???
Interesting constants are probably 0, 1, -1, 0x80000000, and
0x7FFFFFFF. */
#define CNST_0x80000000 (0x20 - 2)
#define CNST_0x7FFFFFFF (0x20 - 3)
#define VALUE_MIN_SIGNED 0x80000000
#define VALUE_MAX_SIGNED 0x7fffffff
#define CNST(n) (0x20 + n)
#define VALUE(n) n
typedef enum
{
#undef DEF_INSN
#define DEF_INSN(SYM,CLASS,NAME) SYM,
#include "insn.def"
} opcode_t;
#define GET_INSN_CLASS(OP) (insn_class[OP])
#define GET_INSN_NAME(OP) (insn_name[OP])
#define UNARY_OPERATION(insn) (GET_INSN_CLASS (insn.opcode) == '1')
typedef struct
{
opcode_t opcode:8;
unsigned int s1:8;
unsigned int s2:8;
unsigned int d:8;
} insn_t;
#if __GNUC__ < 2
#define __CLOBBER_CC
#define __AND_CLOBBER_CC
#else /* __GNUC__ >= 2 */
#define __CLOBBER_CC : "cc"
#define __AND_CLOBBER_CC , "cc"
#endif /* __GNUC__ < 2 */
/* PERFORM_* for all instructions the search uses. These macros are
used both in the search phase and in the test phase. */
#if defined(__GNUC__) && defined(USE_ASM)
/*** Define machine-dependent PERFORM_* here to improve synthesis speed ***/
#if sparc
#define PERFORM_ADD_CIO(d, co, r1, r2, ci) \
asm ("subcc %%g0,%4,%%g0 ! set cy if CI != 0
addxcc %2,%3,%0 ! add R1 and R2
addx %%g0,%%g0,%1 ! set CO to cy" \
: "=r" (d), "=r" (co) \
: "%r" (r1), "rI" (r2), "rI" (ci) \
__CLOBBER_CC)
#define PERFORM_ADD_CO(d, co, r1, r2, ci) \
asm ("addcc %2,%3,%0 ! add R1 and R2
addx %%g0,%%g0,%1 ! set CO to cy" \
: "=r" (d), "=r" (co) \
: "%r" (r1), "rI" (r2) \
__CLOBBER_CC)
#define PERFORM_SUB_CIO(d, co, r1, r2, ci) \
asm ("subcc %%g0,%4,%%g0 ! set cy if CI != 0
subxcc %2,%3,%0 ! subtract R2 from R1
addx %%g0,%%g0,%1 ! set CO to cy" \
: "=r" (d), "=r" (co) \
: "r" (r1), "rI" (r2), "rI" (ci) \
__CLOBBER_CC)
#define PERFORM_SUB_CO(d, co, r1, r2, ci) \
asm ("subcc %2,%3,%0 ! subtract R2 from R1
addx %%g0,%%g0,%1 ! set CO to cy" \
: "=r" (d), "=r" (co) \
: "r" (r1), "rI" (r2) \
__CLOBBER_CC)
#define PERFORM_ADC_CIO(d, co, r1, r2, ci) \
asm ("subcc %4,1,%%g0 ! cy = (CI == 0)
subxcc %2,%3,%0 ! subtract R2 from R1
subx %%g0,-1,%1 ! set CO to !cy" \
: "=&r" (d), "=r" (co) \
: "r" (r1), "rI" (r2), "rI" (ci) \
__CLOBBER_CC)
#define PERFORM_ADC_CO(d, co, r1, r2, ci) \
asm ("subcc %2,%3,%0 ! subtract R2 from R1
subx %%g0,-1,%1 ! set CO to !cy" \
: "=&r" (d), "=r" (co) \
: "r" (r1), "rI" (r2) \
__CLOBBER_CC)
#endif /* sparc */
#if m88k
#define PERFORM_ADD_CIO(d, co, r1, r2, ci) \
asm ("or %0,r0,1
subu.co r0,%4,%0 ; set cy if CI != 0
addu.cio %0,%2,%r3 ; add R1 and R2
addu.ci %1,r0,r0 ; set CO to cy" \
: "=&r" (d), "=r" (co) \
: "%r" (r1), "Or" (r2), "r" (ci))
#define PERFORM_ADD_CO(d, co, r1, r2, ci) \
asm ("addu.co %0,%2,%r3 ; add R1 and R2
addu.ci %1,r0,r0 ; set CO to cy" \
: "=r" (d), "=r" (co) \
: "%r" (r1), "Or" (r2))
#define PERFORM_SUB_CIO(d, co, r1, r2, ci) \
asm ("subu.co r0,r0,%r4 ; reset cy if CI != 0
subu.cio %0,%2,%r3 ; subtract R2 from R1
subu.ci %1,r0,r0 ; set CO to -1+cy
subu %1,r0,%1 ; set CO to !cy" \
: "=r" (d), "=r" (co) \
: "r" (r1), "Or" (r2), "Or" (ci))
#define PERFORM_SUB_CO(d, co, r1, r2, ci) \
asm ("subu.co %0,%2,%r3 ; subtract R2 from R1
subu.ci %1,r0,r0 ; set CO to -1+cy
subu %1,r0,%1 ; set CO to !cy" \
: "=r" (d), "=r" (co) \
: "r" (r1), "Or" (r2))
#define PERFORM_ADC_CIO(d, co, r1, r2, ci) \
asm ("or %0,r0,1
subu.co r0,%r4,%0 ; set cy if CI != 0
subu.cio %0,%2,%r3 ; subtract R2 from R1
addu.ci %1,r0,r0 ; set CO to cy" \
: "=&r" (d), "=r" (co) \
: "r" (r1), "Or" (r2), "Or" (ci))
#define PERFORM_ADC_CO(d, co, r1, r2, ci) \
asm ("subu.co %0,%2,%r3 ; subtract R2 from R1
addu.ci %1,r0,r0 ; set CO to cy" \
: "=r" (d), "=r" (co) \
: "r" (r1), "Or" (r2))
#endif /* m88k */
#endif /* __GNUC__ && USE_ASM*/
/************************* Default PERFORM_* in C *************************/
#define PERFORM_COPY(d, co, r1, ci) \
((d) = (r1), (co) = (ci))
#define PERFORM_EXCHANGE(co, r1, r2, ci) \
do {word __temp = (r1), (r1) = (r2), (r2) = __temp, (co) = (ci);} while (0)
#define PERFORM_ADD(d, co, r1, r2, ci) \
((d) = (r1) + (r2), (co) = (ci))
#ifndef PERFORM_ADD_CIO
#define PERFORM_ADD_CIO(d, co, r1, r2, ci) \
do { word __d = (r1) + (ci); \
word __cy = __d < (ci); \
(d) = __d + (r2); \
(co) = ((d) < __d) + __cy; } while (0)
#endif
#ifndef PERFORM_ADD_CI
#define PERFORM_ADD_CI(d, co, r1, r2, ci) \
do { word __d = (r1) + (r2) + (ci); \
(co) = (ci); \
(d) = __d; } while (0)
#endif
#ifndef PERFORM_ADD_CO
#define PERFORM_ADD_CO(d, co, r1, r2, ci) \
do { word __d = (r1) + (r2); \
(co) = __d < (r1); \
(d) = __d; } while (0)
#endif
#define PERFORM_SUB(d, co, r1, r2, ci) \
((d) = (r1) - (r2), (co) = (ci))
#ifndef PERFORM_SUB_CIO
#define PERFORM_SUB_CIO(d, co, r1, r2, ci) \
do { word __d = (r1) - (r2) - (ci); \
(co) = (ci) ? __d >= (r1) : __d > (r1); \
(d) = __d; } while (0)
#endif
#ifndef PERFORM_SUB_CI
#define PERFORM_SUB_CI(d, co, r1, r2, ci) \
do { word __d = (r1) - (r2) - (ci); \
(co) = (ci); \
(d) = __d; } while (0)
#endif
#ifndef PERFORM_SUB_CO
#define PERFORM_SUB_CO(d, co, r1, r2, ci) \
do { word __d = (r1) - (r2); \
(co) = __d > (r1); \
(d) = __d; } while (0)
#endif
#ifndef PERFORM_ADC_CIO
#define PERFORM_ADC_CIO(d, co, r1, r2, ci) \
do { word __d = (r1) + ~(r2) + (ci); \
(co) = (ci) ? __d <= (r1) : __d < (r1); \
(d) = __d; } while (0)
#endif
#ifndef PERFORM_ADC_CI
#define PERFORM_ADC_CI(d, co, r1, r2, ci) \
do { word __d = (r1) + ~(r2) + (ci); \
(co) = (ci); \
(d) = __d; } while (0)
#endif
#ifndef PERFORM_ADC_CO
#define PERFORM_ADC_CO(d, co, r1, r2, ci) \
do { word __d = (r1) - (r2); \
(co) = __d <= (r1); \
(d) = __d; } while (0)
#endif
#ifndef PERFORM_CMP
#define PERFORM_CMP(d, co, r1, r2, ci) \
((co) = (r1) < (r2))
#endif
#ifndef PERFORM_CMPPAR
#define PERFORM_CMPPAR(d, co, r1, r2, ci) \
do { \
word __x; \
union { long w; short h[2]; char b[4]; } __r1, __r2; \
__r1.w = (r1); __r2.w = (r2); \
__x = ((__r1.h[0] != __r2.h[0]) && (__r1.h[1] != __r2.h[1])) << 14; \
__x |= ((__r1.b[0] != __r2.b[0]) && (__r1.b[1] != __r2.b[1]) \
&& (__r1.b[2] != __r2.b[2]) && (__r1.b[3] != __r2.b[3])) << 12; \
__x |= ((unsigned_word) (r1) >= (unsigned_word) (r2)) << 10; \
__x |= ((unsigned_word) (r1) <= (unsigned_word) (r2)) << 8; \
__x |= ((signed_word) (r1) >= (signed_word) (r2)) << 6; \
__x |= ((signed_word) (r1) <= (signed_word) (r2)) << 4; \
__x |= ((r1) != (r2)) << 2; \
(d) = __x + 0x5554; /* binary 0101010101010100 */ \
(co) = (ci); \
} while (0)
#endif
/* Logic operations that don't affect carry. */
#ifndef PERFORM_AND
#define PERFORM_AND(d, co, r1, r2, ci) \
((d) = (r1) & (r2), (co) = (ci))
#endif
#ifndef PERFORM_IOR
#define PERFORM_IOR(d, co, r1, r2, ci) \
((d) = (r1) | (r2), (co) = (ci))
#endif
#ifndef PERFORM_XOR
#define PERFORM_XOR(d, co, r1, r2, ci) \
((d) = (r1) ^ (r2), (co) = (ci))
#endif
#ifndef PERFORM_ANDC
#define PERFORM_ANDC(d, co, r1, r2, ci) \
((d) = (r1) & ~(r2), (co) = (ci))
#endif
#ifndef PERFORM_IORC
#define PERFORM_IORC(d, co, r1, r2, ci) \
((d) = (r1) | ~(r2), (co) = (ci))
#endif
#ifndef PERFORM_EQV
#define PERFORM_EQV(d, co, r1, r2, ci) \
((d) = (r1) ^ ~(r2), (co) = (ci))
#endif
#ifndef PERFORM_NAND
#define PERFORM_NAND(d, co, r1, r2, ci) \
((d) = ~((r1) & (r2)), (co) = (ci))
#endif
#ifndef PERFORM_NOR
#define PERFORM_NOR(d, co, r1, r2, ci) \
((d) = ~((r1) | (r2)), (co) = (ci))
#endif
/* Logic operations that reset carry. */
#ifndef PERFORM_AND_RC
#define PERFORM_AND_RC(d, co, r1, r2, ci) \
((d) = (r1) & (r2), (co) = 0)
#endif
#ifndef PERFORM_IOR_RC
#define PERFORM_IOR_RC(d, co, r1, r2, ci) \
((d) = (r1) | (r2), (co) = 0)
#endif
#ifndef PERFORM_XOR_RC
#define PERFORM_XOR_RC(d, co, r1, r2, ci) \
((d) = (r1) ^ (r2), (co) = 0)
#endif
#ifndef PERFORM_ANDC_RC
#define PERFORM_ANDC_RC(d, co, r1, r2, ci) \
((d) = (r1) & ~(r2), (co) = 0)
#endif
#ifndef PERFORM_IORC_RC
#define PERFORM_IORC_RC(d, co, r1, r2, ci) \
((d) = (r1) | ~(r2), (co) = 0)
#endif
#ifndef PERFORM_EQV_RC
#define PERFORM_EQV_RC(d, co, r1, r2, ci) \
((d) = (r1) ^ ~(r2), (co) = 0)
#endif
#ifndef PERFORM_NAND_RC
#define PERFORM_NAND_RC(d, co, r1, r2, ci) \
((d) = ~((r1) & (r2)), (co) = 0)
#endif
#ifndef PERFORM_NOR_RC
#define PERFORM_NOR_RC(d, co, r1, r2, ci) \
((d) = ~((r1) | (r2)), (co) = 0)
#endif
/* Logic operations that clobber carry. */
#ifndef PERFORM_AND_CC
#define PERFORM_AND_CC(d, co, r1, r2, ci) \
((d) = (r1) & (r2), (co) = -1)
#endif
#ifndef PERFORM_IOR_CC
#define PERFORM_IOR_CC(d, co, r1, r2, ci) \
((d) = (r1) | (r2), (co) = -1)
#endif
#ifndef PERFORM_XOR_CC
#define PERFORM_XOR_CC(d, co, r1, r2, ci) \
((d) = (r1) ^ (r2), (co) = -1)
#endif
#ifndef PERFORM_ANDC_CC
#define PERFORM_ANDC_CC(d, co, r1, r2, ci) \
((d) = (r1) & ~(r2), (co) = -1)
#endif
#ifndef PERFORM_IORC_CC
#define PERFORM_IORC_CC(d, co, r1, r2, ci) \
((d) = (r1) | ~(r2), (co) = -1)
#endif
#ifndef PERFORM_EQV_CC
#define PERFORM_EQV_CC(d, co, r1, r2, ci) \
((d) = (r1) ^ ~(r2), (co) = -1)
#endif
#ifndef PERFORM_NAND_CC
#define PERFORM_NAND_CC(d, co, r1, r2, ci) \
((d) = ~((r1) & (r2)), (co) = -1)
#endif
#ifndef PERFORM_NOR_CC
#define PERFORM_NOR_CC(d, co, r1, r2, ci) \
((d) = ~((r1) | (r2)), (co) = -1)
#endif
#ifndef PERFORM_LSHIFTR
#define PERFORM_LSHIFTR(d, co, r1, r2, ci) \
((d) = ((unsigned_word) (r1) >> TRUNC_CNT(r2)), \
(co) = (ci))
#endif
#ifndef PERFORM_ASHIFTR
#define PERFORM_ASHIFTR(d, co, r1, r2, ci) \
((d) = ((signed_word) (r1) >> TRUNC_CNT(r2)), \
(co) = (ci))
#endif
#ifndef PERFORM_SHIFTL
#define PERFORM_SHIFTL(d, co, r1, r2, ci) \
((d) = ((signed_word) (r1) << TRUNC_CNT(r2)), (co) = (ci))
#endif
#ifndef PERFORM_ROTATEL
#define PERFORM_ROTATEL(d, co, r1, r2, ci) \
((d) = (r2) == 0 ? (r1) \
: ((r1) << TRUNC_CNT(r2)) | ((r1) >> TRUNC_CNT(BITS_PER_WORD - (r2))),\
(co) = (ci))
#endif
#ifndef PERFORM_LSHIFTR_CO
#define PERFORM_LSHIFTR_CO(d, co, r1, r2, ci) \
do { word __d = ((unsigned_word) (r1) >> TRUNC_CNT(r2)); \
(co) = ((unsigned_word) (r1) >> (TRUNC_CNT(r2) - 1)) & 1; \
(d) = __d; } while (0)
#endif
#ifndef PERFORM_ASHIFTR_CO
#define PERFORM_ASHIFTR_CO(d, co, r1, r2, ci) \
do { word __d = ((signed_word) (r1) >> TRUNC_CNT(r2)); \
(co) = ((signed_word) (r1) >> (TRUNC_CNT(r2) - 1)) & 1; \
(d) = __d; } while (0)
#endif
#ifndef PERFORM_ASHIFTR_CON
#define PERFORM_ASHIFTR_CON(d, co, r1, r2, ci) \
do { word __d = ((signed_word) (r1) >> TRUNC_CNT(r2)); \
(co) = (signed_word) (r1) < 0 \
&& ((r1) << TRUNC_CNT(BITS_PER_WORD - (r2))) != 0; \
(d) = __d; } while (0)
#endif
#ifndef PERFORM_SHIFTL_CO
#define PERFORM_SHIFTL_CO(d, co, r1, r2, ci) \
do { word __d = ((signed_word) (r1) << TRUNC_CNT(r2)); \
(co) = ((r1) >> TRUNC_CNT(BITS_PER_WORD - (r2))) & 1; \
(d) = __d; } while (0)
#endif
#ifndef PERFORM_ROTATEL_CO
#define PERFORM_ROTATEL_CO(d, co, r1, r2, ci) \
((d) = ((r1) << TRUNC_CNT(r2)) | ((r1) >> TRUNC_CNT(BITS_PER_WORD - (r2))),\
(co) = (d) & 1)
#endif
#ifndef PERFORM_ROTATEXL_CIO
#define PERFORM_ROTATEXL_CIO(d, co, r1, r2, ci) \
do { word __d; unsigned cnt = TRUNC_CNT(r2); \
if (cnt == 1) \
{ \
__d = ((r1) << 1) | (ci); \
(co) = (r1) >> (BITS_PER_WORD - 1); \
} \
else \
{ \
__d = ((r1) << cnt) \
| (ci) << (cnt - 1) \
| ((r1) >> (BITS_PER_WORD + 1 - cnt)); \
(co) = ((r1) >> (BITS_PER_WORD - cnt)) & 1; \
} \
(d) = __d; \
} while (0)
#endif
#ifndef PERFORM_EXTS1
#define PERFORM_EXTS1(d, co, r1, r2, ci) \
((d) = ((signed_word) (r1) >> TRUNC_CNT(r2)) << 31 >> 31, (co) = (ci))
#endif
#ifndef PERFORM_EXTS2
#define PERFORM_EXTS2(d, co, r1, r2, ci) \
((d) = ((signed_word) (r1) >> TRUNC_CNT(r2)) << 30 >> 30, (co) = (ci))
#endif
#ifndef PERFORM_EXTU1
#define PERFORM_EXTU1(d, co, r1, r2, ci) \
((d) = ((unsigned_word) (r1) >> TRUNC_CNT(r2)) & 1, (co) = (ci))
#endif
#ifndef PERFORM_EXTU2
#define PERFORM_EXTU2(d, co, r1, r2, ci) \
((d) = ((unsigned_word) (r1) >> TRUNC_CNT(r2)) & 3, (co) = (ci))
#endif
#ifndef PERFORM_DOZ
#define PERFORM_DOZ(d, co, r1, r2, ci) \
(((d) = (signed_word) (r1) > (signed_word) (r2) ? (r1) - (r2) : 0), \
(co) = (ci))
#endif
#ifndef PERFORM_CPEQ
#define PERFORM_CPEQ(d, co, r1, r2, ci) \
((d) = ((r1) == (r2)) << 31, (co) = (ci))
#endif
#ifndef PERFORM_CPGE
#define PERFORM_CPGE(d, co, r1, r2, ci) \
((d) = ((signed_word) (r1) >= (signed_word) (r2)) << 31, (co) = (ci))
#endif
#ifndef PERFORM_CPGEU
#define PERFORM_CPGEU(d, co, r1, r2, ci) \
((d) = ((unsigned_word) (r1) >= (unsigned_word) (r2)) << 31, (co) = (ci))
#endif
#ifndef PERFORM_CPGT
#define PERFORM_CPGT(d, co, r1, r2, ci) \
((d) = ((signed_word) (r1) > (signed_word) (r2)) << 31, (co) = (ci))
#endif
#ifndef PERFORM_CPGTU
#define PERFORM_CPGTU(d, co, r1, r2, ci) \
((d) = ((unsigned_word) (r1) > (unsigned_word) (r2)) << 31, (co) = (ci))
#endif
#ifndef PERFORM_CPLE
#define PERFORM_CPLE(d, co, r1, r2, ci) \
((d) = ((signed_word) (r1) <= (signed_word) (r2)) << 31, (co) = (ci))
#endif
#ifndef PERFORM_CPLEU
#define PERFORM_CPLEU(d, co, r1, r2, ci) \
((d) = ((unsigned_word) (r1) <= (unsigned_word) (r2)) << 31, (co) = (ci))
#endif
#ifndef PERFORM_CPLT
#define PERFORM_CPLT(d, co, r1, r2, ci) \
((d) = ((signed_word) (r1) < (signed_word) (r2)) << 31, (co) = (ci))
#endif
#ifndef PERFORM_CPLTU
#define PERFORM_CPLTU(d, co, r1, r2, ci) \
((d) = ((unsigned_word) (r1) < (unsigned_word) (r2)) << 31, (co) = (ci))
#endif
#ifndef PERFORM_CPNEQ
#define PERFORM_CPNEQ(d, co, r1, r2, ci) \
((d) = ((r1) != (r2)) << 31, (co) = (ci))
#endif
#ifndef PERFORM_CMPEQ
#define PERFORM_CMPEQ(d, co, r1, r2, ci) \
((d) = (r1) == (r2), (co) = (ci))
#endif
#ifndef PERFORM_CMPLE
#define PERFORM_CMPLE(d, co, r1, r2, ci) \
((d) = (signed_word) (r1) <= (signed_word) (r2), (co) = (ci))
#endif
#ifndef PERFORM_CMPLEU
#define PERFORM_CMPLEU(d, co, r1, r2, ci) \
((d) = (unsigned_word) (r1) <= (unsigned_word) (r2), (co) = (ci))
#endif
#ifndef PERFORM_CMPLT
#define PERFORM_CMPLT(d, co, r1, r2, ci) \
((d) = (signed_word) (r1) < (signed_word) (r2), (co) = (ci))
#endif
#ifndef PERFORM_CMPLTU
#define PERFORM_CMPLTU(d, co, r1, r2, ci) \
((d) = (unsigned_word) (r1) < (unsigned_word) (r2), (co) = (ci))
#endif
/* Unary operations. */
#ifndef PERFORM_CLZ
#define PERFORM_CLZ(d, co, r1, ci) \
do { \
int __a; \
__a = (r1) <= 0xffff \
? ((r1) <= 0xff ? 0 : 8) \
: ((r1) <= 0xffffff ? 16 : 24); \
(d) = clz_tab[(r1) >> __a] - __a; \
(co) = (ci); \
} while (0)
#endif
#ifndef PERFORM_CTZ
/* This can be done faster using the (x & -x) trick. */
#define PERFORM_CTZ(d, co, r1, ci) \
do { \
int __a; \
__a = ((r1) & 0xffff == 0) \
? (((r1) & 0xff0000) == 0 ? 24 : 16) \
: ((r1) & 0xff == 0) ? 8 : 0; \
(d) = ctz_tab[((r1) >> __a) & 0xff] + __a; \
(co) = (ci); \
} while (0)
#endif
#ifndef PERFORM_FF1
#define PERFORM_FF1(d, co, r1, ci) \
do { \
int __a; \
__a = (r1) <= 0xffff \
? ((r1) <= 0xff ? 0 : 8) \
: ((r1) <= 0xffffff ? 16 : 24); \
(d) = ff1_tab[(r1) >> __a] + __a; \
(co) = (ci); \
FF1_CHECK(d,r1) \
} while (0)
#endif
#if m88k
#define FF1_CHECK(d,r1) \
{ int t; \
asm ("ff1 %0,%1" : "=r" (t) : "r" (r1)); \
if (t != (d)) abort (); }
#else
#define FF1_CHECK(d,r1)
#endif
#ifndef PERFORM_FF0
#define PERFORM_FF0(d, co, r1, ci) \
PERFORM_FF1(d, co, ~(r1), ci)
#endif
#ifndef PERFORM_FFS
#define PERFORM_FFS(d, co, r1, ci) \
do { \
int __a; \
word __x = (r1) & (-r1); \
PERFORM_CLZ(d, co, __x, ci); \
(d) = 32 - (d); \
} while (0)
#endif
#ifndef PERFORM_ABSVAL
#define PERFORM_ABSVAL(d, co, r1, ci) \
((d) = (signed_word) (r1) < 0 ? -(r1) : (r1), (co) = (ci))
#endif
#ifndef PERFORM_NABSVAL
#define PERFORM_NABSVAL(d, co, r1, ci) \
((d) = (signed_word) (r1) > 0 ? -(r1) : (r1), (co) = (ci))
#endif
#ifndef PERFORM_CMOVEQ
#define PERFORM_CMOVEQ(d, co, r1, r2, ci) \
((d) = (r1) == 0 ? (r2) : (d), (co) = (ci))
#endif
#ifndef PERFORM_CMOVNE
#define PERFORM_CMOVNE(d, co, r1, r2, ci) \
((d) = (r1) != 0 ? (r2) : (d), (co) = (ci))
#endif
#ifndef PERFORM_CMOVLT
#define PERFORM_CMOVLT(d, co, r1, r2, ci) \
((d) = (signed_word) (r1) < 0 ? (r2) : (d), (co) = (ci))
#endif
#ifndef PERFORM_CMOVGE
#define PERFORM_CMOVGE(d, co, r1, r2, ci) \
((d) = (signed_word) (r1) >= 0 ? (r2) : (d), (co) = (ci))
#endif
#ifndef PERFORM_CMOVLE
#define PERFORM_CMOVLE(d, co, r1, r2, ci) \
((d) = (signed_word) (r1) <= 0 ? (r2) : (d), (co) = (ci))
#endif
#ifndef PERFORM_CMOVGT
#define PERFORM_CMOVGT(d, co, r1, r2, ci) \
((d) = (signed_word) (r1) > 0 ? (r2) : (d), (co) = (ci))
#endif
#ifndef PERFORM_INVDIV
#define PERFORM_INVDIV(v, co, r1, ci) \
do { \
word __q, __r; \
udiv_qrnnd (__q, __r, -(r1), 0, (r1)); \
(v) = __q; \
(co) = (ci); \
} while (0)
#endif
#ifndef PERFORM_INVMOD
#define PERFORM_INVMOD(v, co, r1, ci) \
do { \
word __q, __r; \
udiv_qrnnd (__q, __r, -(r1), 0, (r1)); \
(v) = __r; \
(co) = (ci); \
} while (0)
#endif
#ifndef PERFORM_MUL
#define PERFORM_MUL(v, co, r1, r2, ci) \
do { \
(v) = (r1) * (r2); \
(co) = (ci); \
} while (0)
#endif
#ifndef PERFORM_UMULWIDEN_HI
#define PERFORM_UMULWIDEN_HI(v, co, r1, r2, ci) \
do { \
word __ph, __pl; \
umul_ppmm (__ph, __pl, (r1), (r2)); \
(v) = __ph; \
(co) = (ci); \
} while (0)
#endif
#ifdef UDIV_WITH_SDIV
#define PERFORM_SDIV(v, co, r1, r2, ci) \
do { \
if ((r2) != 0) \
(v) = (signed_word) (r1) / (signed_word) (r2); \
else \
(v) = 0; \
(co) = (ci); \
} while (0)
#endif /* UDIV_WITH_SDIV */
enum goal_func
{
#undef DEF_GOAL
#define DEF_GOAL(SYM,ARITY,NAME,CODE) SYM,
#undef DEF_SYNONYM
#define DEF_SYNONYM(SYM,NAME)
#include "goal.def"
LAST_AND_UNUSED_GOAL_CODE
};
enum prune_flags
{
NO_PRUNE = 0,
CY_0 = 1,
CY_1 = 2,
CY_JUST_SET = 4,
};
void
synth(insn_t *sequence,
int n_insns,
word *values,
int n_values,
word desired_value,
int allowed_cost,
int cy_in,
int flags);
void
test_sequence(insn_t *sequence, int n_insns);
int
run_program(insn_t *sequence, int n_insns, word *values);
extern const char clz_tab[];
extern const char ctz_tab[];
extern const char ff1_tab[];